package com.fzj.example.reference;

import java.lang.ref.*;

/**
 * ClassName: ObjectParse
 * date: 2019/10/10 11:09
 * Description: 引用状态迁移改变
 * @author fanzj@bonree.com
 * @since JDK 1.8
 */
public class ObjectParse {

    public static ReferenceQueue<Object> rq = new ReferenceQueue< Object >();

    public static void main(String[] args) throws InterruptedException {

        /**********************************引用状态迁移分析*********************/
        //创建一个引用队列
        ReferenceQueue q=new ReferenceQueue();
        //弱引用创建，Inactive状态,此时Reference.pending状态为null,next=null;
        WeakReference reference=new WeakReference(new Object(),q);
        System.out.println(reference);
        //垃圾回收,弱引用，所以回收该object对象，reference的状态为PENDING
        System.gc();
        /* ReferenceHandler线程从pending中取下该元素，并且将该元素放入到queue中，此时Reference状态为ENQUEUED，Reference.queue = ReferenceEnqueued */
        /* 当从queue里面取出该元素，则变为INACTIVE，Reference.queue = Reference.NULL */
        Reference ref = q.remove();
        System.out.println(ref);
        //ref与reference相同，说明引用状态再迁移

        /*********************************软引用分析,内存不足快oom回收***************************/
        System.out.println("*****软引用*****");
        Object obj=new Object();
        SoftReference<Object> sr=new SoftReference<>(obj,rq);
        System.out.println(sr.get()!=null);
        System.gc();
        obj=null;
        System.out.println(sr.get()!=null);
        System.gc();
        System.out.println(sr.get()!=null);
        /*********************************弱引用分析,只要 GC 发现一个对象只有弱引用，则就会回收此弱引用对***************************/
        System.out.println("*****弱引用*****");
        Object obj2=new Object();
        WeakReference<Object> wr=new WeakReference<>(obj2,rq);
        System.out.println(wr.get()!=null);
        //代码顺序obj2,System.gc()顺序
        //在指向 obj = null 语句之前，Object对象有两条引用路径，其中一条为obj强引用类型，另一条为wr弱引用类型，
        //当执行了obj = null.Object 对象就只具有弱引用，并且我们进行了显示的垃圾回收
        obj2=null;
        System.gc();
        System.out.println("obj2,System.gc()顺序：先obj2=null,则为false,先gc则为true"+wr.get()!=null);
        System.out.println(wr.get()!=null);
        System.gc();
        System.out.println(wr.get()!=null);
        /*********************************虚引用分析,虚引用并不会影响对象的生命周期 虚引用的作用为：跟踪垃圾回收器收集对象这一活动的情况***************************/
        System.out.println("*****虚引用*****");
        Object obj3=new Object();
        PhantomReference<Object> pr=new PhantomReference<>(obj3,rq);
        System.out.println(wr.get()!=null);
        obj3=null;
        System.gc();
        System.out.println(wr.get()!=null);
        Reference<Object> rfpr= (Reference< Object >) rq.poll();
        if(rfpr!=null){
            System.out.println("回收");
        }

    }
}
